package com.wwj.admin.controller;


import com.wwj.common.GlobalStatic;
import com.wwj.core.system.entity.User;
import com.wwj.core.system.service.IUserService;
import com.wwj.framework.annotation.SystemControllerLog;
import com.wwj.framework.controller.BaseController;
import com.wwj.shiro.ShiroUser;
import com.wwj.utils.CaptchaUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created by xya on 16-10-24.
 */
@Controller
@RequestMapping("/auth")
public class AuthController extends BaseController {

    public static final String LOGIN_URL = "/login";

    public static final String REGISTER_URL = "/register";

    @Resource
    private IUserService userService;



    @Value("#{resourceProperties['prefix.screen.app.url']}")
    private String qrCodePrefix;

    //@Resource
    //private IUserLoginService userLoginService;

   /* @Resource
    private FreeMarkerConfigurer configurer;*/

    //@Resource
    //private IUserRoleMenuService userRoleMenuService;

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(Model model, HttpServletRequest request) throws Exception {
        //判断用户是否登录
        if (SecurityUtils.getSubject().isAuthenticated()) {
            return redirect + "/index";
        }
        //默认赋值message,避免freemarker尝试从session取值,造成异常
        model.addAttribute("message", "");
        return LOGIN_URL;
    }

    @SystemControllerLog(description = "后台登录操作")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(User currUser, HttpSession session, Model model, HttpServletRequest request) {
        Subject user = SecurityUtils.getSubject();
        // 验证码
        /*
         * String code = (String) session.getAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM); if
		 * (StringUtils.isNotBlank(code)) { code = code.toLowerCase().toString(); } String submitCode =
		 * WebUtils.getCleanParam(request, GlobalStatic.DEFAULT_CAPTCHA_PARAM); if (StringUtils.isNotBlank(submitCode))
		 * { submitCode = submitCode.toLowerCase().toString(); } if (StringUtils.isBlank(submitCode) ||
		 * StringUtils.isBlank(code) || !code.equals(submitCode)) { model.addAttribute("message", "验证码错误!"); return
		 * LOGIN_URL; }
		 */

        UsernamePasswordToken token = new UsernamePasswordToken(currUser.getAccount(), currUser.getPassword());
        // FrameAuthenticationToken token = new FrameAuthenticationToken(currUser.getAccount(), currUser.getPassword());

        String rememberme = request.getParameter("rememberme");
        if (StringUtils.isNotBlank(rememberme)) {
            token.setRememberMe(true);
        } else {
            token.setRememberMe(false);
        }

        try {
            // 会调用 shiroDbRealm 的认证方法
            // org.springrain.frame.shiro.ShiroDbRealm.doGetAuthenticationInfo(AuthenticationToken)
            user.login(token);
            ShiroUser u = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
            //user.getSession().setAttribute(Constants.SHIRO_USER_SHOP_ID,u.getShopId());
            //获取当前登录人
            ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
            String ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }

            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }

//            UserLogin ul = new UserLogin(shiroUser.getId(), ip, request.getHeader("user-agent"));
//            try {
//                userLoginService.logUserLogin(ul);
//            } catch (Exception e) {
//                logger.error(e.getMessage(), e);
//            }
        } catch (UnknownAccountException uae) {
            model.addAttribute("message", "账号不存在!");
            return LOGIN_URL;
        } catch (IncorrectCredentialsException ice) {
            model.addAttribute("message", "密码错误!");
            return LOGIN_URL;
        } catch (LockedAccountException lae) {
            model.addAttribute("message", "账号被锁定!");
            return LOGIN_URL;
        } catch (Exception e) {
            model.addAttribute("message", "未知错误,请联系管理员.");
            logger.error(e.getMessage());
            return LOGIN_URL;
        }
        // String sessionId = session.getId();
        // Cache<Object, Object> cache = shiroCacheManager.getCache(GlobalStatic.authenticationCacheName);
        // cache.put(GlobalStatic.authenticationCacheName+"-"+currUser.getAccount(), sessionId);
        /*
         * Cache<String, Object> cache = shiroCacheManager.getCache(GlobalStatic.shiroActiveSessionCacheName);
		 * Serializable oldSessionId = (Serializable) cache.get(currUser.getAccount()); if(oldSessionId!=null){ Subject
		 * subject=new Subject.Builder().sessionId(oldSessionId).buildSubject(); subject.logout(); }
		 * cache.put(currUser.getAccount(), session.getId());
		 */
        Map m = model.asMap();
        return redirect + "/index";
    }


    /**
     * 退出
     *
     * @param request
     */
    @RequestMapping(value = "/logout")
    public String logout(HttpServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            subject.logout();
        }
        return LOGIN_URL;
        // request.getSession().invalidate();
    }


    /**
     * 自动登录,无需账号密码,测试代码,默认注释，根据实际修改
     *
     * @param model
     * @param request
     * @param response
     * @return
     * @throws Exception

    // @RequestMapping(value = "/auto/login")
    public String autologin(Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
    ShiroUser shiroUser = new ShiroUser();
    shiroUser.setId("admin");
    shiroUser.setName("admin");
    shiroUser.setAccount("admin");
    SimplePrincipalCollection principals = new SimplePrincipalCollection(shiroUser,
    GlobalStatic.authorizingRealmName);
    WebSubject.Builder builder = new WebSubject.Builder(request, response);
    builder.principals(principals);
    builder.authenticated(true);
    WebSubject subject = builder.buildWebSubject();
    ThreadContext.bind(subject);
    return redirect + INDEX_URL;
    }*/

    /**
     * 生成验证码
     *
     * @return
     * @throws IOException
     */
    @RequestMapping("/getCaptcha")
    public void getCaptcha(HttpSession session, HttpServletResponse response) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG);
        CaptchaUtils tool = new CaptchaUtils();
        StringBuffer code = new StringBuffer();
        BufferedImage image = tool.genRandomCodeImage(code);
        session.removeAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM);
        session.setAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM, code.toString());
        // 将内存中的图片通过流动形式输出到客户端
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }



    @RequestMapping(value = "/check")
    @ResponseBody
    public boolean check(String key, String value, HttpSession session) {
        try {
            switch (key) {
                case "phone":
                    return !userService.checkUserPhone(value);
                case "captcha":
                    return session.getAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM).toString().toLowerCase().equals(value.toLowerCase());
                default:
                    return false;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }
}
